# coding: utf-8
'''

单例模式
利用可变对象可改变的特性, 将实例放入一个可变对象中
生成实例的时候去这个可变对象中取或者存取
'''

# 1. 使用 __new__ 方法

class Singleton(object):
	'''
	The most base type
	
	'''
	def __new__(cls, *args, **kwargs):
		if not hasattr(cls, '_instance'):
			# 1.
			orig = super(Singleton, cls) # 调用父类的方法, 解决多重继承的问题
			# print orig.__doc__
			# print Singleton.__doc__
			# print cls.__doc__
			# print object.__doc__
			cls._instance = orig.__new__(cls, *args, **kwargs) # orig 是超类, 创建类实例
			# 2.
			# cls._instance = object.__new__(cls, *args, **kwargs) # 创建类实例
		return cls._instance

class MyClass(Singleton):
	'''

	子类'''
	a = 1

a = MyClass()
a1 = MyClass()

print a == a1
print id(a)
print id(a1)


# 2.共享属性
class Borg(object):
	'''

	建实例时把所有实例的__dict__指向同一个字典,这样它们具有相同的属性和方法.
	注意: 实例的属性指向了_state指向的可变对象{}, 因此才能共享属性
	'''
	_state = {} # 

	def __new__(cls, *args, **kwargs):
		instance = super(Borg, cls).__new__(cls, *args, **kwargs)
		instance.__dict__ = cls._state # 共享类作用域里的属性
		return instance

class MyClass(Borg):
	a = 1

a = MyClass()
a1 = MyClass()
print a1.a
print a._state
print a1._state
a.a = 2
print a._state
print a1._state

a = {}
b = a
b['a'] = 1111
print a

# 3.装饰器
def singleton(cls, *args, **kwargs):
	instances = {}
	def getInstance():
		if cls not in instances:
			instances[cls] = cls(*args, **kwargs)
		return instances[cls]
	return getInstance

@singleton
class MyClass():
	pass

a = MyClass()
a1 = MyClass()
print a == a1

# 4.import, Python每个文件都是一个单例模式
from mysingleton import mySingleton
print id(mySingleton)

from mysingleton import mySingleton
print id(mySingleton)